#include <common/global_data.h>
#include <common/file.h>
#include <common/environment.h>
#include <config/conf_parse.h>
#include <ifaddrs.h>
#include <sys/types.h>
#include <unistd.h>

AtomicHashMap<uint64_t, std::string, 256> GlobalData::task_id_map_;

namespace{
    //返回当前执行的进程的路径
    const std::string& kEmptyString = "";
    std::string program_path(){
        char path[4096];
        auto len = readlink("proc/self/exe", path , sizeof(path) - 1);
        if(len == -1 ){
            return kEmptyString;
        }
    
        path[len] = '\0';
    
        return std::string(path);
    }
    }
GlobalData::GlobalData() {

    InitConfig();
    //获取进程ID
    porcess_id_ = getpid();
    auto prog_path = program_path();

    if(!prog_path.empty()){
        process_group_ = GetFileName(prog_path) + "_" + std::to_string(porcess_id_);
    }else{
        process_group_ = "cmw_default_" + std::to_string(porcess_id_);
    }
}

uint64_t GlobalData::RegisterTaskName(const std::string& task_name) {
    auto id = Hash(task_name);
    while (task_id_map_.Has(id))
    {
        std::string* name = nullptr;
        task_id_map_.Get(id, &name);
        if(task_name == *name){
            break;
        }
        ++id;
        std::cout << "Task name hash collision: " << task_name << " <=> " << *name;
    }

    task_id_map_.Set(id, task_name);
    return id;
}

std::string GlobalData::GetTaskNameById(uint64_t id){
    std::string* task_name = nullptr;
    if(task_id_map_.Get(id, &task_name)){
        return *task_name;
    }
    return kEmptyString;
}


// 读取 cmw/conf/cmw.pb.conf并解析
bool GlobalData::InitConfig() {

    std::string config_path("cmw/conf/cmw.pb.conf");

    config_path = GetAbsolutePath(WorkRoot(), "conf/cmw.pb.conf");
 if (!GetCmwConfFromFile(config_path, &config_)) {
   std::cout << "Read cmw/conf/cmw.pb.conf from absolute path failed!" << std::endl;
   return false;
 }
 std::cout << "Read cmw/conf/cmw.pb.conf from absolute path sucess!"<< std::endl;
 return true;
}

const CmwConfig& GlobalData::Config() const { return config_; }


void GlobalData::SetProcessGroup(const std::string& process_group) {
    process_group_ = process_group;
}

const std::string& GlobalData::ProcessGroup() const { return process_group_; }